跳到主要内容

Docker 与 Kubernetes 的关系

学 Docker 的过程中,几乎一定会听到 Kubernetes(常简写为 K8s)这个名字。很多人会有疑问:它们是不是一类东西?学了 Docker 还要不要学 K8s?网上说「K8s 弃用 Docker」又是怎么回事?

这篇附录就把这些问题一次讲清楚。

各自解决的问题​

Docker 和 K8s 不是竞品,它们解决的是两个不同层面的问题。

Docker 解决的是单机上的容器化问题:怎么把应用打包成镜像,怎么在一台机器上把容器跑起来。 具体包括:

  • 用 Dockerfile 定义镜像,把应用和依赖环境打包成一个标准交付物。
  • 用 docker run 在单机上创建、启动、管理容器。
  • 用 Volume 管理单机上的数据持久化,用 Docker 网络实现单机内容器之间的通信。
  • 用 Docker Compose 编排单机上的多个容器(比如一个应用 + 一个数据库)。

Kubernetes 解决的是多机环境下的容器编排调度问题:当容器要跑在几十、几百台机器组成的集群上时,怎么管理它们。 具体包括:

  • 调度:一个新容器应该放到集群里哪台机器上跑?K8s 根据资源占用、亲和性等规则自动决策。
  • 自愈:容器挂了自动重启,节点宕机了把上面的容器迁移到其他节点重新拉起。
  • 扩缩容:流量大了就把容器副本从 2 个加到 10 个,流量小了再缩回来。
  • 服务发现与负载均衡:容器副本分布在不同机器上,IP 还会变,K8s 用 Service 提供固定入口并分发流量。
  • 滚动更新与回滚:发布新版本时逐步替换旧容器,出问题一键回滚。
  • 配置与存储管理:统一管理集群级别的配置(ConfigMap/Secret)和存储(PV/PVC)。
一句话理解

Docker 管「一台机器上怎么跑容器」,Kubernetes 管「一群机器上怎么跑容器」。Docker 是容器技术本身,K8s 是容器的集群管理者。

可以打个比方:Docker 是一辆汽车(负责把货物装好并跑起来),Kubernetes 是一个物流调度中心(负责决定成百上千辆车各走哪条路、哪辆坏了派新的顶上)。

概念对照​

学过 Docker 再看 K8s,很多概念都能找到对应关系。下面这张表可以作为入门时的「翻译表」:

Docker 世界Kubernetes 世界说明
Container(容器)Container(容器)最底层运行单元是同一个东西,K8s 里跑的容器和 Docker 跑的本质相同
docker run 启动的单个容器PodK8s 的最小调度单位。一个 Pod 通常只装一个容器,也可以装多个紧密协作的容器,共享网络和存储
Docker ComposeDeployment + ServiceCompose 在单机上编排多容器;Deployment 负责在集群里维持 N 个 Pod 副本并支持滚动更新,Service 提供固定访问入口和负载均衡
docker-compose.yml各种 YAML 资源清单都是声明式配置:写好期望状态,工具负责达成。K8s 的资源种类更多(Deployment、Service、Ingress 等)
Volume(数据卷)PV(PersistentVolume)+ PVC(PersistentVolumeClaim)Volume 挂在单机上;PV 是集群里的存储资源,PVC 是应用对存储的申请,两者分离后可以对接云盘、NFS 等各种后端
Docker 网络(bridge、容器间互通)Service + IngressDocker 网络解决单机内容器互通;Service 解决集群内跨机器访问一组 Pod,Ingress 负责把集群外的 HTTP/HTTPS 流量引进来
Dockerfile / 镜像完全沿用K8s 不构建镜像,直接使用符合 OCI 标准的镜像,Docker 构建的镜像可以直接用
Docker Hub / 私有 Registry完全沿用K8s 同样从镜像仓库拉取镜像,Docker Hub、Harbor 等都能直接用
Docker Engine(dockerd)CRI 容器运行时(如 containerd)K8s 通过 CRI 接口调用运行时来真正启动容器,现在主流是 containerd,而 containerd 正是 Docker 底层也在用的组件
提示

记这张表不用一次记住,先在脑子里建立「单机 Docker 命令 → 集群 K8s 资源」的映射直觉,后面学 K8s 时每个新概念都能挂到已知的 Docker 概念上,会轻松很多。

演进关系​

K8s 和 Docker 的关系在历史上变过一次,这也是「K8s 弃用 Docker」这个误解的来源。时间线大致如下:

  1. 早期(2014 年前后):K8s 刚诞生时,Docker 几乎是唯一的容器运行时,所以 K8s 直接调用 Docker(dockerd)来启动容器。
  2. dockershim 阶段:后来出现了其他容器运行时(如 rkt、containerd),K8s 为了统一对接各种运行时,定义了 CRI(Container Runtime Interface,容器运行时接口)标准。但 Docker 当时没有实现 CRI 接口,K8s 只好在代码里专门维护一个叫 dockershim 的适配层,作为 K8s 和 Docker 之间的「翻译官」。
  3. K8s 1.20(2020 年):官方宣布 dockershim 进入弃用流程,推荐使用 containerd 等原生支持 CRI 的运行时。
  4. K8s 1.24(2022 年):正式移除 dockershim。此后 K8s 默认通过 containerd 来运行容器——而 containerd 本来就是 Docker 引擎内部的底层组件,Docker 自己在 2016 年把它拆出来捐给了 CNCF。

Docker 与 Kubernetes 调用链对比

可以看到,变化只是 K8s 不再绕经 dockerd,而是直接调用 containerd,链路更短了。

澄清常见误解:「K8s 弃用 Docker」≠ 不能用 Docker

这是容器圈流传最广的一个误解。准确的说法是:K8s 弃用的是 dockershim 这个适配层,而不是 Docker 这个工具,更不是 Docker 镜像。

  • K8s 运行的镜像遵循 OCI(Open Container Initiative)标准,而 docker build 构建出来的镜像天然就是 OCI 镜像。
  • 所以用 Docker 构建的镜像照样能在 K8s 上正常跑,不需要任何改造。
  • 日常开发中,你依然可以在本地用 Docker 写 Dockerfile、构建镜像、推到仓库,K8s 集群拉下来就能运行。

真正受影响的只有一类人:集群运维人员需要把节点的容器运行时从 dockerd 换成 containerd。对普通开发者来说,Docker 该怎么用还怎么用。

新手学习路径建议​

对新手来说,顺序很重要,建议先 Docker,后 K8s:

  1. 先学好 Docker:理解镜像、容器、Volume、网络这几个核心概念,会写 Dockerfile,会用 Docker Compose 编排单机多容器。本系列前面的文章覆盖的就是这部分内容。
  2. Docker 熟练后再碰 K8s:K8s 的所有概念(Pod、Deployment、Service、PV/PVC)都建立在容器之上,没有 Docker 基础直接学 K8s,会被大量抽象概念淹没,学得很痛苦。
  3. 入门 K8s 从本地环境开始:不要一上来就折腾云上的多节点集群,先用 Docker Desktop 自带的 Kubernetes、minikube 或 kind 在本地起一个单节点集群,跟着官方教程把 Deployment 和 Service 跑通。
  4. 带着对照表学:学每个 K8s 概念时,回头想想它对应 Docker 里的什么(参考上面的概念对照表),用已知带动未知。
提示

如果你的目标只是「把自己的小项目跑起来」,单机 Docker + Compose 往往就够了,不一定需要 K8s。K8s 解决的是规模化、高可用场景下的管理问题,项目没到那个体量时引入 K8s 反而是负担。按需学习即可。